
package com.wolfeyes.framework.springsecurity.domain.model;

import java.util.List;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;

import cn.hutool.core.util.ReflectUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
 * @description 作者有话说：随着企业云原生的火热及微服务大行其道，现在的程序几乎都是前后端分离的项目程序（99%以上，你懂我意思吧~）
 * @description 基于这样的项目实践背景，梳理出了前后端分离认证的大致思路，而且前后端分离不同于传统的web服务，无法使用session，因此我们采用JWT这种无状态机制来生成token。
 * @description Spring Security默认的表单登录认证的过滤器是UsernamePasswordAuthenticationFilter，这个过滤器并不适用于前后端分离的架构，
 * @description 因此我们需要自定义一个过滤器和携带Token的自定义实体类。请注意：在系统某些业务场景下，不要直接使用此默认构造方法创建的对象，否则容易产生未知错误！
 * @description 因为默认构造方法创建的对象是半成品，未完成属性的设值注入，此对象实例需要通过json框架设值注入或手动setter设值，去完成实例化和初始化操作。
 * @description 权限框架Apache Shiro特点小巧而精美，简单易用，并没有Spring Security做的功能强大，这点毋庸置疑，并不只是一个量级的差别，你懂我意思吧~
 * @description 但是在实际开发工作时可能并不需要那么复杂的东西，所以使用小而简单的 Shiro 就足够了。对于它俩到底哪个好，这个不必纠结，能更简单的解决项目问题就好了。
 * @description 就个人而言，Spring Security虽然比较重，但是真的好用，尤其是实现Oauth2.0规范，还能与出身名门的SpringBoot无缝整合，非常简单方便，灵活可扩展。
 * @description 讲真，如果项目经费和实力允许，类似的企业安全认证需求我还是推荐使用 OAuth2 中的 password 模式，你懂我意思吧~
 * @description SpringSecurity安全认证权限框架
 * @title 封装用户登录输入的信息
 * @title 自定义的用户登录对象
 * @see Talk is cheap, Show me the code. -- Linus Torvalds
 * @author yanyljava
 * @create 2022-01-13 21:25
 */
//@Data
@Getter
public class CustomizeUsernamePasswordAuthenticationToken extends UsernamePasswordAuthenticationToken {

	/**
	 * @description 串行版本标识
	 */
	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
	
	/**
	 * 用户名
	 */
	private String userName;

	/**
	 * 用户密码
	 */
	private String password;

	/**
	 * 验证码
	 */
	//private String code;
	private String checkCode;
	
	/**
	 * @title 默认构造方法
	 */
	public CustomizeUsernamePasswordAuthenticationToken() {
		super("", "");
	}
	
	/*private final CustomizeLoginBody customizeLoginBody;
	
	public CustomizeUsernamePasswordAuthenticationToken(Object principal, Object credentials, CustomizeLoginBody customizeLoginBody) {
		super(principal, credentials);
		this.customizeLoginBody = customizeLoginBody;
	}

	public CustomizeUsernamePasswordAuthenticationToken(Object principal, Object credentials, List<GrantedAuthority> authorities, CustomizeLoginBody customizeLoginBody) {
		super(principal, credentials, authorities);
		this.customizeLoginBody = customizeLoginBody;
	}

	/ *
	public CustomizeLoginBody getCustomizeLoginBody() {
		return this.customizeLoginBody;
	}*/
	
	public void setUserName(String userName) {
		//super.principal设值注入-userName
		ReflectUtil.setFieldValue(this, "principal", userName);
		this.userName = userName;
	}
	
	public void setPassword(String password) {
		//super.credentials设值注入-password
		ReflectUtil.setFieldValue(this, "credentials", password);
		this.password = password;
	}
	
}

